package com.mlethe.library.recyclerview.decoration;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import android.view.View;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;

import com.mlethe.library.recyclerview.pagergrid.PagerGridLayoutManager;

/**
 * 分页滑动网格布局分割线(StaggeredGridLayoutManager 模式分割线会占据item的高度)
 *
 * @author Mlethe
 * @date 2021/7/30
 */
public class PagerGridItemDecoration extends RecyclerView.ItemDecoration {
    private Context mContext;
    private Drawable mDivider;
    private Drawable mMarginDivider;
    /**
     * 垂直空隙大小
     */
    private int mVerticalSize;
    /**
     * 水平空隙大小
     */
    private int mHorizontalSize;
    /**
     * 顶部Margin大小
     */
    private int mTopMarginSize;
    /**
     * 底部Margin大小
     */
    private int mBottomMarginSize;
    /**
     * 左边Margin大小
     */
    private int mLeftMarginSize;
    /**
     * 右边Margin大小
     */
    private int mRightMarginSize;

    public PagerGridItemDecoration(Context context) {
        this.mContext = context.getApplicationContext();
    }

    /**
     * 设置drawable
     *
     * @param drawableId
     */
    public PagerGridItemDecoration setDrawable(@DrawableRes int drawableId) {
        return setDrawable(ContextCompat.getDrawable(mContext, drawableId));
    }

    /**
     * 设置drawable
     *
     * @param drawable
     */
    public PagerGridItemDecoration setDrawable(Drawable drawable) {
        mDivider = drawable;
        return this;
    }

    /**
     * 设置颜色
     *
     * @param colorRes
     */
    public PagerGridItemDecoration setColor(@ColorRes int colorRes) {
        return setColorInt(ContextCompat.getColor(mContext, colorRes));
    }

    /**
     * 设置颜色
     *
     * @param color
     */
    public PagerGridItemDecoration setColorInt(@ColorInt int color) {
        mDivider = new ColorDrawable(color);
        return this;
    }

    /**
     * 设置颜色
     *
     * @param colorString
     */
    public PagerGridItemDecoration setColor(String colorString) {
        return setColorInt(Color.parseColor(colorString));
    }

    /**
     * 设置边框drawable
     *
     * @param drawableId
     */
    public PagerGridItemDecoration setMarginDrawable(@DrawableRes int drawableId) {
        return setMarginDrawable(ContextCompat.getDrawable(mContext, drawableId));
    }

    /**
     * 设置边框drawable
     *
     * @param drawable
     */
    public PagerGridItemDecoration setMarginDrawable(Drawable drawable) {
        mMarginDivider = drawable;
        return this;
    }

    /**
     * 设置边框颜色
     *
     * @param colorRes
     */
    public PagerGridItemDecoration setMarginColor(@ColorRes int colorRes) {
        return setMarginColorInt(ContextCompat.getColor(mContext, colorRes));
    }

    /**
     * 设置边框颜色
     *
     * @param color
     */
    public PagerGridItemDecoration setMarginColorInt(@ColorInt int color) {
        mMarginDivider = new ColorDrawable(color);
        return this;
    }

    /**
     * 设置边框颜色
     *
     * @param colorString
     */
    public PagerGridItemDecoration setMarginColor(String colorString) {
        return setMarginColorInt(Color.parseColor(colorString));
    }

    /**
     * 设置空隙大小
     *
     * @param size dp
     * @return
     */
    public PagerGridItemDecoration setSize(float size) {
        return setSize(dp2px(size));
    }

    /**
     * 设置空隙大小
     *
     * @param size px
     * @return
     */
    public PagerGridItemDecoration setSize(int size) {
        this.mVerticalSize = size;
        this.mHorizontalSize = size;
        return this;
    }

    /**
     * 设置垂直空隙大小
     *
     * @param size dp
     * @return
     */
    public PagerGridItemDecoration setVerticalSize(float size) {
        return setVerticalSize(dp2px(size));
    }

    /**
     * 设置垂直空隙大小
     *
     * @param size px
     * @return
     */
    public PagerGridItemDecoration setVerticalSize(int size) {
        this.mVerticalSize = size;
        return this;
    }

    /**
     * 设置水平空隙大小
     *
     * @param size dp
     * @return
     */
    public PagerGridItemDecoration setHorizontalSize(float size) {
        return setHorizontalSize(dp2px(size));
    }

    /**
     * 设置水平空隙大小
     *
     * @param size px
     * @return
     */
    public PagerGridItemDecoration setHorizontalSize(int size) {
        this.mHorizontalSize = size;
        return this;
    }

    /**
     * 设置左右Margin大小
     *
     * @param left  dp
     * @param right dp
     * @return
     */
    public PagerGridItemDecoration setHorizontalMarginSize(float left, float right) {
        return setHorizontalMarginSize(dp2px(left), dp2px(right));
    }

    /**
     * 设置左右Margin大小
     *
     * @param left  px
     * @param right px
     * @return
     */
    public PagerGridItemDecoration setHorizontalMarginSize(int left, int right) {
        this.mLeftMarginSize = left;
        this.mRightMarginSize = right;
        return this;
    }

    /**
     * 设置上下Margin大小
     *
     * @param top    dp
     * @param bottom dp
     * @return
     */
    public PagerGridItemDecoration setVerticalMarginSize(float top, float bottom) {
        return setVerticalMarginSize(dp2px(top), dp2px(bottom));
    }

    /**
     * 设置上下Margin大小
     *
     * @param top    px
     * @param bottom px
     * @return
     */
    public PagerGridItemDecoration setVerticalMarginSize(int top, int bottom) {
        this.mTopMarginSize = top;
        this.mBottomMarginSize = bottom;
        return this;
    }

    /**
     * 设置Margin大小（dp）
     *
     * @param left
     * @param top
     * @param right
     * @param bottom
     * @return
     */
    public PagerGridItemDecoration setMarginSize(float left, float top, float right, float bottom) {
        return setMarginSize(dp2px(left), dp2px(top), dp2px(right), dp2px(bottom));
    }

    /**
     * 设置Margin大小（px）
     *
     * @param left   左
     * @param top    上
     * @param right  右
     * @param bottom 下
     * @return
     */
    public PagerGridItemDecoration setMarginSize(int left, int top, int right, int bottom) {
        this.mLeftMarginSize = left;
        this.mTopMarginSize = top;
        this.mRightMarginSize = right;
        this.mBottomMarginSize = bottom;
        return this;
    }

    /**
     * 设置Margin大小（dp）
     *
     * @param size
     * @return
     */
    public PagerGridItemDecoration setMarginSize(float size) {
        return setMarginSize(dp2px(size));
    }

    /**
     * 设置Margin大小（px）
     *
     * @param size
     * @return
     */
    public PagerGridItemDecoration setMarginSize(int size) {
        this.mLeftMarginSize = size;
        this.mTopMarginSize = size;
        this.mRightMarginSize = size;
        this.mBottomMarginSize = size;
        return this;
    }

    /**
     * 设置左右Margin大小
     *
     * @param size dp
     * @return
     */
    public PagerGridItemDecoration setHorizontalMarginSize(float size) {
        return setHorizontalMarginSize(dp2px(size));
    }

    /**
     * 设置左右Margin大小
     *
     * @param size px
     * @return
     */
    public PagerGridItemDecoration setHorizontalMarginSize(int size) {
        this.mLeftMarginSize = size;
        this.mRightMarginSize = size;
        return this;
    }

    /**
     * 设置上下Margin大小
     *
     * @param size dp
     * @return
     */
    public PagerGridItemDecoration setVerticalMarginSize(float size) {
        return setVerticalMarginSize(dp2px(size));
    }

    /**
     * 设置上下Margin大小
     *
     * @param size px
     * @return
     */
    public PagerGridItemDecoration setVerticalMarginSize(int size) {
        this.mTopMarginSize = size;
        this.mBottomMarginSize = size;
        return this;
    }

    /**
     * 获取垂直空隙大小
     *
     * @return
     */
    public int getVerticalSize() {
        return mVerticalSize;
    }

    /**
     * 获取水平空隙大小
     *
     * @return
     */
    public int getHorizontalSize() {
        return mHorizontalSize;
    }

    /**
     * 获取上边Margin大小
     *
     * @return
     */
    public int getTopMarginSize() {
        return mTopMarginSize;
    }

    /**
     * 获取下边Margin大小
     *
     * @return
     */
    public int getBottomMarginSize() {
        return mBottomMarginSize;
    }

    /**
     * 获取左边Margin大小
     *
     * @return
     */
    public int getLeftMarginSize() {
        return mLeftMarginSize;
    }

    /**
     * 获取右边Margin大小
     *
     * @return
     */
    public int getRightMarginSize() {
        return mRightMarginSize;
    }

    /**
     * dp转px
     *
     * @param dp
     * @return
     */
    private int dp2px(float dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mContext.getResources().getDisplayMetrics());
    }

    /**
     * 设置条目周边的偏移量
     *
     * @param outRect 接收输出的Rect
     * @param view childView
     * @param parent RecyclerView
     * @param state RecyclerView的当前状态
     */
    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        mContext = null;
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (!(layoutManager instanceof PagerGridLayoutManager)) {
            return;
        }
        PagerGridLayoutManager pagerGridLayoutManager = (PagerGridLayoutManager) layoutManager;
        int row = pagerGridLayoutManager.getRow();
        if (row == -1) {
            return;
        }
        int column = pagerGridLayoutManager.getColumn();
        if (column == -1) {
            return;
        }
        int position = layoutManager.getPosition(view);
        if (position < 0) {
            return;
        }
        int left;
        int top;
        int right;
        int bottom;
        boolean reverseLayout = pagerGridLayoutManager.getReverseLayout();
        if (reverseLayout) {
            if (isFirstColumn(position, column)) {
                // 第一列
                right = mRightMarginSize;
            } else {
                right = mHorizontalSize / 2;
            }
            if (isLastColumn(position, column)) {
                // 最后一列
                left = mLeftMarginSize;
            } else {
                left = mHorizontalSize / 2;
            }
            if (isFirstRow(position, column, row)) {
                // 第一行
                top = mTopMarginSize;
            } else {
                top = mVerticalSize / 2;
            }
            if (isLastRow(position, column, row)) {
                // 最后一行
                bottom = mBottomMarginSize;
            } else {
                bottom = mVerticalSize / 2;
            }
        } else {
            if (isFirstColumn(position, column)) {
                // 第一列
                left = mLeftMarginSize;
            } else {
                left = mHorizontalSize / 2;
            }
            if (isLastColumn(position, column)) {
                // 最后一列
                right = mRightMarginSize;
            } else {
                right = mHorizontalSize / 2;
            }
            if (isFirstRow(position, column, row)) {
                // 第一行
                top = mTopMarginSize;
            } else {
                top = mVerticalSize / 2;
            }
            if (isLastRow(position, column, row)) {
                // 最后一行
                bottom = mBottomMarginSize;
            } else {
                bottom = mVerticalSize / 2;
            }
        }
        outRect.set(left, top, right, bottom);
    }

    /**
     * 绘制在图层的最下层
     *
     * @param canvas 画布
     * @param parent RecyclerView
     * @param state RecyclerView的当前状态
     */
    @Override
    public void onDraw(@NonNull Canvas canvas, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (!(layoutManager instanceof PagerGridLayoutManager)) {
            return;
        }
        PagerGridLayoutManager pagerGridLayoutManager = (PagerGridLayoutManager) layoutManager;
        int row = pagerGridLayoutManager.getRow();
        if (row == -1) {
            return;
        }
        int column = pagerGridLayoutManager.getColumn();
        if (column == -1) {
            return;
        }
        boolean reverseLayout = pagerGridLayoutManager.getReverseLayout();
        if (reverseLayout) {
            reverseDrawDividers(canvas, parent, row, column);
        } else {
            drawDividers(canvas, parent, row, column);
        }
    }

    /**
     * 绘制在图层的最上层
     *
     * @param canvas 画布
     * @param parent RecyclerView
     * @param state RecyclerView的当前状态
     */
    @Override
    public void onDrawOver(@NonNull Canvas canvas, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
    }

    /**
     * 正向绘制
     *
     * @param canvas 画布
     * @param parent RecyclerView
     * @param row 网络布置的行数
     * @param column 网络布置的列数
     */
    private void drawDividers(@NonNull Canvas canvas, @NonNull RecyclerView parent, int row, int column) {
        // 绘制
        int childCount = parent.getChildCount();
        RecyclerView.Adapter adapter = parent.getAdapter();
        if (adapter == null) {
            return;
        }
        int itemCount = adapter.getItemCount();
        for (int i = 0; i < childCount; i++) {
            View childView = parent.getChildAt(i);
            int position = parent.getChildAdapterPosition(childView);

            if (position < 0 || position >= itemCount) {
                continue;
            }
            // 计算水平分割线的位置
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) childView.getLayoutParams();
            // 画水平分隔线
            // 第一行
            if (mMarginDivider != null && isFirstRow(position, column, row) && mTopMarginSize > 0) {
                int left = childView.getLeft() - layoutParams.leftMargin;
                if (isFirstColumn(position, column)) {
                    left -= mLeftMarginSize;
                }
                int right = childView.getRight() + layoutParams.rightMargin;
                if (isLastColumn(position, column)) {
                    right += mRightMarginSize;
                } else {
                    right += mHorizontalSize;
                }
                int bottom = childView.getTop() - layoutParams.topMargin;
                int top = bottom - mTopMarginSize;
                mMarginDivider.setBounds(left, top, right, bottom);
                mMarginDivider.draw(canvas);
            }
            if (isLastRow(position, column, row)) {
                // 最后一行
                if (mMarginDivider != null && mBottomMarginSize > 0) {
                    int left = childView.getLeft() - layoutParams.leftMargin;
                    if (isFirstColumn(position, column)) {
                        left -= mLeftMarginSize;
                    }
                    int right = childView.getRight() + layoutParams.rightMargin;
                    if (isLastColumn(position, column)) {
                        right += mRightMarginSize;
                    } else {
                        right += mHorizontalSize;
                    }
                    int top = childView.getBottom() + layoutParams.bottomMargin;
                    int bottom = top + mBottomMarginSize;
                    mMarginDivider.setBounds(left, top, right, bottom);
                    mMarginDivider.draw(canvas);
                }
            } else {
                if (mDivider != null) {
                    int left = childView.getLeft() - layoutParams.leftMargin;
                    int right = childView.getRight() + layoutParams.rightMargin;
                    if (!isLastColumn(position, column)) {
                        right += mHorizontalSize;
                    }
                    int top = childView.getBottom() + layoutParams.bottomMargin;
                    int bottom = top + mVerticalSize;
                    mDivider.setBounds(left, top, right, bottom);
                    mDivider.draw(canvas);
                }
            }
            // 画垂直分割线
            // 第一列
            if (mMarginDivider != null && isFirstColumn(position, column) && mLeftMarginSize > 0) {
                int top = childView.getTop() - layoutParams.topMargin;
                int bottom = childView.getBottom() + layoutParams.bottomMargin;
                if (!isLastRow(position, column, row)) {
                    bottom += mVerticalSize;
                }
                int right = childView.getLeft() - layoutParams.leftMargin;
                int left = right - mLeftMarginSize;
                mMarginDivider.setBounds(left, top, right, bottom);
                mMarginDivider.draw(canvas);
            }
            if (isLastColumn(position, column)) {
                // 最后一列
                if (mMarginDivider == null || mRightMarginSize <= 0) {
                    continue;
                }
                int top = childView.getTop() - layoutParams.topMargin;
                int bottom = childView.getBottom() + layoutParams.bottomMargin;
                if (!isLastRow(position, column, row)) {
                    bottom += mVerticalSize;
                }
                int left = childView.getRight() + layoutParams.rightMargin;
                int right = left + mRightMarginSize;
                mMarginDivider.setBounds(left, top, right, bottom);
                mMarginDivider.draw(canvas);
            } else {
                if (mDivider == null || mHorizontalSize <= 0) {
                    continue;
                }
                int top = childView.getTop() - layoutParams.topMargin;
                int bottom = childView.getBottom() + layoutParams.bottomMargin;
                int left = childView.getRight() + layoutParams.rightMargin;
                int right = left + mHorizontalSize;
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
        }
    }

    /**
     * 反向绘制
     *
     * @param canvas 画布
     * @param parent RecyclerView
     * @param row 网络布置的行数
     * @param column 网络布置的列数
     */
    private void reverseDrawDividers(@NonNull Canvas canvas, @NonNull RecyclerView parent, int row, int column) {
        // 绘制
        int childCount = parent.getChildCount();
        RecyclerView.Adapter adapter = parent.getAdapter();
        if (adapter == null) {
            return;
        }
        int itemCount = adapter.getItemCount();
        for (int i = 0; i < childCount; i++) {
            View childView = parent.getChildAt(i);
            int position = parent.getChildAdapterPosition(childView);

            if (position < 0 || position >= itemCount) {
                continue;
            }
            // 计算水平分割线的位置
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) childView.getLayoutParams();
            // 从右往左，画水平分隔线
            // 第一行
            if (mMarginDivider != null && isFirstRow(position, column, row) && mTopMarginSize > 0) {
                int left = childView.getLeft() - layoutParams.leftMargin;
                if (isLastColumn(position, column)) {
                    left -= mLeftMarginSize;
                } else {
                    left -= mHorizontalSize;
                }
                int right = childView.getRight() + layoutParams.rightMargin;
                if (isFirstColumn(position, column)) {
                    right += mRightMarginSize;
                }
                int bottom = childView.getTop() - layoutParams.topMargin;
                int top = bottom - mTopMarginSize;
                mMarginDivider.setBounds(left, top, right, bottom);
                mMarginDivider.draw(canvas);
            }
            if (isLastRow(position, column, row)) {
                // 最后一行
                if (mMarginDivider != null && mBottomMarginSize > 0) {
                    int left = childView.getLeft() - layoutParams.leftMargin;
                    if (isLastColumn(position, column)) {
                        left -= mLeftMarginSize;
                    } else {
                        left -= mHorizontalSize;
                    }
                    int right = childView.getRight() + layoutParams.rightMargin;
                    if (isFirstColumn(position, column)) {
                        right += mRightMarginSize;
                    }
                    int top = childView.getBottom() + layoutParams.bottomMargin;
                    int bottom = top + mBottomMarginSize;
                    mMarginDivider.setBounds(left, top, right, bottom);
                    mMarginDivider.draw(canvas);
                }
            } else {
                if (mDivider != null) {
                    int left = childView.getLeft() - layoutParams.leftMargin;
                    if (!isLastColumn(position, column)) {
                        left -= mHorizontalSize;
                    }
                    int right = childView.getRight() + layoutParams.rightMargin;
                    int top = childView.getBottom() + layoutParams.bottomMargin;
                    int bottom = top + mVerticalSize;
                    mDivider.setBounds(left, top, right, bottom);
                    mDivider.draw(canvas);
                }
            }
            // 画垂直分割线
            // 第一列
            if (mMarginDivider != null && isFirstColumn(position, column) && mRightMarginSize > 0) {
                int top = childView.getTop() - layoutParams.topMargin;
                int bottom = childView.getBottom() + layoutParams.bottomMargin;
                if (!isLastRow(position, column, row)) {
                    bottom += mVerticalSize;
                }
                int left = childView.getRight() + layoutParams.rightMargin;
                int right = left + mRightMarginSize;
                mMarginDivider.setBounds(left, top, right, bottom);
                mMarginDivider.draw(canvas);
            }
            if (isLastColumn(position, column)) {
                // 最后一列
                if (mMarginDivider == null || mLeftMarginSize <= 0) {
                    continue;
                }
                int top = childView.getTop() - layoutParams.topMargin;
                int bottom = childView.getBottom() + layoutParams.bottomMargin;
                if (!isLastRow(position, column, row)) {
                    bottom += mVerticalSize;
                }
                int right = childView.getLeft() - layoutParams.leftMargin;
                int left = right - mLeftMarginSize;
                mMarginDivider.setBounds(left, top, right, bottom);
                mMarginDivider.draw(canvas);
            } else {
                if (mDivider == null || mHorizontalSize <= 0) {
                    continue;
                }
                int top = childView.getTop() - layoutParams.topMargin;
                int bottom = childView.getBottom() + layoutParams.bottomMargin;
                int right = childView.getLeft() - layoutParams.leftMargin;
                int left = right - mHorizontalSize;
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
        }
    }

    /**
     * 第一行
     *
     * @return
     */
    private boolean isFirstRow(int position, int column, int row) {
        // 当前的位置 % (行数 * 列数) < 列数
        return position % (row * column) < column;
    }

    /**
     * 最后一行
     *
     * @return
     */
    private boolean isLastRow(int position, int column, int row) {
        // 当前的位置 % (行数 * 列数) >= (行数 * 列数) - 列数
        int product = row * column;
        return position % product >= product - column;
    }

    /**
     * 第一列
     *
     * @return
     */
    private boolean isFirstColumn(int position, int column) {
        // (当前的位置 + 1) % 列数 == 1
        if (column == 1) return true;
        return (position + 1) % column == 1;
    }

    /**
     * 最后一列
     *
     * @return
     */
    private boolean isLastColumn(int position, int column) {
        // (当前的位置 + 1) % 列数 == 0
        return (position + 1) % column == 0;
    }
}
